#include "PCH.h"
#include "RenderDevice.h"
#include "RenderHelper.h"

using namespace DeviousRenderer;

DeRenderDevice* DeRenderDevice::m_spRenderInst = 0;

DeRenderDevice::DeRenderDevice()
: m_pDevice(NULL)
{

}

DeRenderDevice::~DeRenderDevice()
{

}

DeRenderDevice* DeRenderDevice::Get()
{
	if (!m_spRenderInst)
	{
		m_spRenderInst = new DeRenderDevice();
	}

	return m_spRenderInst;
}

void DeRenderDevice::Destory()
{
	SAFE_DELETE(m_spRenderInst);
}

DeRasterizerStatePtr DeRenderDevice::CreateRasterizerState(const DeRasterizerDescription& desc)
{
	D3D11_RASTERIZER_DESC d3d11Desc;
	ZeroMemory(&d3d11Desc, sizeof(D3D11_RASTERIZER_DESC));
	d3d11Desc.FillMode = ConvertFillMode(desc.FillMode);
	d3d11Desc.CullMode = ConvertCullMode(desc.CullMode);
	d3d11Desc.FrontCounterClockwise = true;
	d3d11Desc.DepthBias = desc.DepthBias;
	d3d11Desc.DepthBiasClamp = 0;
	d3d11Desc.SlopeScaledDepthBias = d3d11Desc.SlopeScaledDepthBias;
	d3d11Desc.MultisampleEnable = desc.EnableMSAA;
	d3d11Desc.MultisampleEnable = desc.EnableLineAA;
	d3d11Desc.ScissorEnable = true;

	ID3D11RasterizerState* RasterizerState;
	m_pDevice->CreateRasterizerState(&d3d11Desc, &RasterizerState);
	DeD3D11RasterizerState* D3D11RasterizerState = new DeD3D11RasterizerState(RasterizerState);

	//TOCHECK: if memory leak
	return D3D11RasterizerState;


}

DeTexture2DPtr DeRenderDevice::CreateTexture2D(Texture2DConfig* config, D3D11_SUBRESOURCE_DATA* pData /* = NULL */)
{
	

}

DeRenderTargetView*	DeRenderDevice::CreateRenderTargetView(const Texture2D* texture2D)
{
	
	
}

DeDepthStencilView* DeRenderDevice::CreateDepthStencilView(const Texture2D* texture2D)
{
	ID3D11DepthStencilView* pDSV = NULL;
	HRESULT hr = m_pDevice->CreateDepthStencilView(texture2D->GetResource(), NULL, &pDSV);
	DeDepthStencilView* pDeDepthStencilView = new DeDepthStencilView(pDSV);
	return pDeDepthStencilView;
}

DeShaderReflection*	DeRenderDevice::GenerateReflection(const DeShader* pShader, std::map<std::string, DeShaderParameter*>& parametersMap)
{
	DeShaderReflection*	shaderReflection = new DeShaderReflection();
	ID3D11ShaderReflection*	d3d11Reflector = NULL;
	if (FAILED(D3DReflect(pShader->m_pCompiledShader->GetBufferPointer(), pShader->m_pCompiledShader->GetBufferSize(),
		IID_ID3D11ShaderReflection, (void**)&d3d11Reflector)))
	{
		//TODO
	}

	D3D11_SHADER_DESC shaderDesc;
	d3d11Reflector->GetDesc(&shaderDesc);
	shaderReflection->SetShaderDescription(shaderDesc);

	for (int i = 0; i < shaderDesc.InputParameters; i ++)
	{
		D3D11_SIGNATURE_PARAMETER_DESC paramDesc;
		d3d11Reflector->GetInputParameterDesc(&paramDesc);
		shaderReflection->AddInputParameters(paramDesc);
	}
	for (int i = 0; i < shaderDesc.OutputParameters; i ++)
	{
		D3D11_SIGNATURE_PARAMETER_DESC paramDesc;
		d3d11Reflector->GetOutputParameterDesc(&paramDesc);
		shaderReflection->AddOutputParameters(paramDesc);
	}

	for (int i = 0; i < shaderDesc.ConstantBuffers; i ++)
	{
		ID3D11ShaderReflectionConstantBuffer* constBuffer = d3d11Reflector->GetConstantBufferByIndex(i);

		D3D11_SHADER_BUFFER_DESC bufferDesc;
		constBuffer->GetDesc(&bufferDesc);

		if (bufferDesc.Type == D3D_CT_CBUFFER || bufferDesc.Type == D3D_CT_TBUFFER)
		{

		}
	}
}